<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
  // **默认绑定** ：常用的函数调用类型：独立函数调用
  // * 可以把这个规则看作是无法应用其他规则的时候默认的规则，基本指向的是window
  // function fn(){
  //     console.log(this);// window
  // }
  // fn();
  //
  // const obj = {
  //     run(){
  //         console.log(this);
  //     }
  // }
  // const run = obj.run;
  // run();


  // **隐式绑定** ：如果函数调用时，前面存在调用它的对象，那么this就会隐式绑定到这个对象上
  //
  // * 当函数引用有上下文对象的时候（obj），隐式绑定规则会把函数中的this绑定到这个上下文对象上
  // const obj = {
  //     fn(){
  //         console.log(this===obj);// true
  //     }
  // }
  // obj.fn();

  // * 隐式绑定可能会出现隐式丢失的问题 ：被隐式绑定的函数，会丢失了绑定对象
  // const obj = {
  //     fn(){
  //         console.log(this);// window
  //     }
  // }
  // const fn = obj.fn;
  // fn();


  // **显式绑定**： 指我们通过call、apply以及bind方法改变this的行为，
  // 相比隐式绑定，我们能清楚的感知 this 指向变化过程。
  // var userName = "window";
  // function fn(){
  //     console.log(this.userName);
  // }
  // const obj = {
  //     userName:"obj"
  // }
  // fn();// window
  // fn.call(obj);// obj



  // **`new`绑定**：构造函数只是一些使用new操作符被调用的函数,使用new调用函数的时候，
  // 会构造一新的对象，这个时候 就把新的对象绑定给了函数的this上
  // function Box(){
  //     console.log(this);
  // }
  // new Box();


  //
  // * 函数是否在new中调用，如果是的话，this绑定的是新创建的对象
  // * 函数是否通过call、apply（显示绑定）调用，如果是，则this绑定的是执行的对象
  // * 函数是否在某个上下文对象中调用(隐式绑定)，如果有，则this绑定在这个上下文对象上
  // * 如果以上都不是 则默认绑定 执行window

  const obj = {
      fn:function(){
          console.log(this);
      }
  }
  // new obj.fn();
  // obj.fn.call({a:1,b:2})
  const run  = obj.fn;
  run();

</script>
</html>